package com.edu.mybatisplus.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.sql.SQLException;

@MapperScan("com.edu.mybatisplus.mapper")
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        // 如果sql中包含 “/* no_logic_delete */” 标记，则不执行逻辑删除
        interceptor.addInnerInterceptor(new InnerInterceptor() {
            @Override
            public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
                String sql = boundSql.getSql();
                try {
                    if (sql.contains("/* no_logic_delete */")) {
                        // 使用 JSqlParser 解析 SQL
                        Statement statement = CCJSqlParserUtil.parse(sql);

                        if (statement instanceof Select) {
                            PlainSelect plainSelect = (PlainSelect) ((Select) statement).getSelectBody();

                            // 如果 WHERE 子句存在，则替换逻辑删除条件
                            if (plainSelect.getWhere() != null) {
                                String modifiedWhere = plainSelect.getWhere().toString()
                                        .replace("IS_DELETED = 0", "1 = 1")  // 替换 "deleted = 0" 为 "1 = 1"
                                        .replace("is_deleted = 0", "1 = 1");  // 处理大小写不一致的情况
                                plainSelect.setWhere(CCJSqlParserUtil.parseCondExpression(modifiedWhere));
                            }
                        }

                        // 更新 SQL
                        MetaObject metaObject = SystemMetaObject.forObject(boundSql);
                        metaObject.setValue("sql", statement.toString());
                    }
                } catch (JSQLParserException e) {
                    throw new RuntimeException("解析SQL失败", e);
                }
            }
        });

        // 添加乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}
